package com.huatech.support.shiro;

import java.util.HashSet;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;

import com.huatech.core.domain.User;
import com.huatech.core.service.PermService;
import com.huatech.core.service.RoleService;
import com.huatech.core.service.UserService;

@Component
public class SystemAuthorizingRealm extends AuthorizingRealm {
	
	@Resource UserService userService;
	@Resource RoleService roleService;
	@Resource PermService permService;

	/**
	 * 角色、权限认证
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String username = (String) principals.getPrimaryPrincipal();
		Set<String> roles = new HashSet<String>(roleService.findByUsername(username));
		Set<String> perms = new HashSet<String>();
		if(roles != null && roles.size() > 0) {
			perms = new HashSet<String>(permService.findByRoles(roles));
		}
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(roles);
		authorizationInfo.addStringPermissions(perms);
		return authorizationInfo;
	}

	/**
	 * 身份认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username = (String) token.getPrincipal();
		User user = userService.findByUsername(username);
		if(user == null) {
			throw new UnauthenticatedException();
		}
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, user.getPassword(), getName());
		authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(username));
		return authenticationInfo;
	}
	
	@Override
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("md5");
		matcher.setHashIterations(1);
		super.setCredentialsMatcher(matcher);
	}
	
	
	@Override
	public String getName() {
		return this.getClass().getSimpleName();
	}

}
